use std::os;
use std::collections::HashMap;
+use std::io::File;
+use serialize::Decodable;
use core::registry::PackageRegistry;
-use core::{MultiShell, Source, SourceId, PackageSet, Target, PackageId, resolver};
+use core::{MultiShell, Source, SourceId, PackageSet, Target, PackageId, Resolve, resolver};
use ops;
use sources::{PathSource};
use util::config::{Config, ConfigValue};
-use util::{CargoResult, Wrap, config, internal, human, ChainError};
+use util::{CargoResult, Wrap, config, internal, human, ChainError, toml};
pub struct CompileOptions<'a> {
pub update: bool,
let source_ids = package.get_source_ids();
let (packages, resolve, sources) = {
+ let lockfile = manifest_path.dir_path().join("Cargo.lock");
+ let source_id = package.get_package_id().get_source_id();
+
let mut config = try!(Config::new(*shell, update, jobs, target.clone()));
let mut registry =
try!(PackageRegistry::new(source_ids, override_ids, &mut config));
- let resolved = try!(resolver::resolve(package.get_package_id(),
- package.get_dependencies(),
- &mut registry));
+ let resolved = match try!(load_lockfile(&lockfile, source_id)) {
+ Some(r) => r,
+ None => {
+ try!(resolver::resolve(package.get_package_id(),
+ package.get_dependencies(),
+ &mut registry))
+ }
+ };
let req: Vec<PackageId> = resolved.iter().map(|r| r.clone()).collect();
let packages = try!(registry.get(req.as_slice()).wrap({
Ok(test_executables)
}
+fn load_lockfile(path: &Path, sid: &SourceId) -> CargoResult<Option<Resolve>> {
+ // If there is no lockfile, return none.
+ let mut f = match File::open(path) {
+ Ok(f) => f,
+ Err(_) => return Ok(None)
+ };
+
+ let s = try!(f.read_to_string());
+
+ let mut d = ::toml::Decoder::new(::toml::Table(try!(toml::parse(s.as_slice(), path))));
+ let v: resolver::EncodableResolve = Decodable::decode(&mut d).unwrap();
+ Ok(Some(try!(v.to_resolve(sid))))
+}
+
fn source_ids_from_config(configs: &HashMap<String, config::ConfigValue>,
cur_path: Path) -> CargoResult<Vec<SourceId>> {
debug!("loaded config; configs={}", configs);
try!(walk_tree(&pwd, |mut file| {
let path = file.path().clone();
let contents = try!(file.read_to_string());
- let file = path.filename_display().to_string();
- let table = try!(cargo_toml::parse(contents.as_slice(),
- file.as_slice()).chain_error(|| {
+ let table = try!(cargo_toml::parse(contents.as_slice(), &path).chain_error(|| {
internal(format!("could not parse Toml manifest; path={}",
path.display()))
}));
fn extract_config(mut file: io::fs::File, key: &str) -> CargoResult<ConfigValue> {
let contents = try!(file.read_to_string());
- let mut toml = try!(cargo_toml::parse(contents.as_slice(),
- file.path().filename_display()
- .to_string().as_slice()));
+ let mut toml = try!(cargo_toml::parse(contents.as_slice(), file.path()));
let val = try!(toml.pop(&key.to_string()).require(|| internal("")));
ConfigValue::from_toml(file.path(), val)
let contents = try!(str::from_utf8(contents).require(|| {
human("Cargo.toml is not valid UTF-8")
}));
- let root = try!(parse(contents, "Cargo.toml"));
+ let root = try!(parse(contents, &Path::new("Cargo.toml")));
let mut d = toml::Decoder::new(toml::Table(root));
let toml_manifest: TomlManifest = match Decodable::decode(&mut d) {
Ok(t) => t,
}
}
-pub fn parse(toml: &str, file: &str) -> CargoResult<toml::Table> {
+pub fn parse(toml: &str, file: &Path) -> CargoResult<toml::Table> {
let mut parser = toml::Parser::new(toml.as_slice());
match parser.parse() {
Some(toml) => return Ok(toml),
let (loline, locol) = parser.to_linecol(error.lo);
let (hiline, hicol) = parser.to_linecol(error.hi);
error_str.push_str(format!("{}:{}:{}{} {}\n",
- file,
+ file.filename_display(),
loline + 1, locol + 1,
if loline != hiline || locol != hicol {
format!("-{}:{}", hiline + 1,